%%% @author linzhj <linzhj@35info.cn>
%%% @copyright (C) 2010, linzhj
%%% @doc
%%%    
%%% @end
%%% Created : 2011-12-09 by linzhj <linzhj@35info.cn>


-module(http_client).

-export([get/1, get/2, post/2, post/4]).

-export([asyn_get/2, asyn_get/4, asyn_post/3, asyn_post/6]).

asyn_get(Url, Callback)->
    asyn_get(Url, [], Callback, 3).

asyn_get(_Url, _Headers, _Callback, 0)->
    "";
asyn_get(Url, Headers, Callback, Retry)->
    RetryFunction = fun() -> asyn_get(Url, Headers, Callback, Retry-1) end,
    Receiver = 
	fun(Response)-> 
		Body = get_body(Response, RetryFunction), 
		Callback(Body) 
	end,
    httpc:request(get, {Url, Headers}, [{timeout, get_timeout()}], [{sync, false}, {receiver, Receiver}]),
    ok.

get(Url)->
    get(Url, []).

get(Url, Headers)->
    get(Url, Headers, 3).

get(_Url, _Headers, 0)->
    "";

get(Url, Headers, Retry)->
    RetryFunction = fun() -> get(Url, Headers, Retry-1) end,
    util:log("Get Url:~p~n",[Url]),
    Response = httpc:request(get, {Url, Headers}, [{timeout, get_timeout()}], []),
    get_body(Response, RetryFunction).

post(Url, Body)->
    post(Url, [], "application/x-www-form-urlencoded", Body).

post(Url, Headers, ContentType, Body)->
    post(Url, Headers, ContentType, Body, 3).

post(_Url, _Headers, _ContentType, _Body,0)->
    "";

post(Url, Headers, ContentType, Body, Retry)->
    ReturnFunction = fun()-> post(Url, Headers, ContentType, Body, Retry-1) end,
    %% data_helper:format("Post Url:~p~nBody:~p~n",[Url, Body]),
    Response = httpc:request(post, {Url, Headers, ContentType, Body},[{timeout, get_timeout()}],[]), 
    get_body(Response, ReturnFunction).

asyn_post(Url, Body, Callback)->
    asyn_post(Url, [], "application/x-www-form-urlencoded", Body, Callback, 0).

asyn_post(_Url, _Headers, _ContentType, _Body, _Callback, 0)->
    "";
asyn_post(Url, Headers, ContentType, Body, Callback, Retury)->
    %% data_helper:format("Post Url:~p~nBody:~p~n",[Url, Body]),
    Receiver = 
	fun(Response)-> 
		Body = get_body(Response, fun()->asyn_post(Url, Headers, ContentType, Body, Callback, Retury-1) end), 
		Callback(Body) 
	end,
    httpc:request(post, {Url, Headers, ContentType, Body},[{timeout, get_timeout()}],[{sync, false}, {receiver, Receiver}]).

get_body(Response, RetryFunction)->
    %% util:log("Response:~p~n",[Response]),
    %% util:log("RetryFunction:~p~n",[RetryFunction]),
    case Response of 
	{_RId, saved_to_file} -> "";
	{error, {connect_failed, _}} ->
	    RetryFunction();
	{error, etimeout}->
	    RetryFunction();
	{error, timeout}->
	    RetryFunction();
	{error, _Reason} -> "";
	{ok, {503, _}} -> % 服务器无法访问
	    RetryFunction();
	{ok, {408, _}} -> % 超时
	    RetryFunction();
	{ok, {_, Body}}->
	    Body;
	{ok, {{_, 503, _}, _, _}} -> % 服务器无法访问
	    RetryFunction();
	{ok, {{_, 408, _}, _, _}} -> % 超时
	    RetryFunction();
	{ok, {_, _, Body}}->
	    Body;
	Other ->
	    log(Other),
	    ""
    end.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
get_timeout()->
    5000.


log(Message)->
    util:log("Message:~p~n",[Message]).
